//
// Created on 2025/7/19.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".

#ifndef STREAMCORE_CONVERTER_H
#define STREAMCORE_CONVERTER_H
#include <napi/native_api.h>

template <typename T, typename Enabled = void> struct NapiValueConverter {
    static napi_value From(napi_env env, const T &value) { static_assert(true, "type not supported"); }
    static T As(napi_env env, napi_value value) { static_assert(true, "type not supported"); }
    static bool Validate(napi_env env, napi_value value) { static_assert(true, "type not supported"); }
};

template <> struct NapiValueConverter<int32_t> {
    static napi_value From(napi_env env, const int32_t &value) {
        napi_value result;
        napi_create_int32(env, value, &result);
        return result;
    }
    static int32_t As(napi_env env, napi_value value) {
        int32_t result;
        napi_get_value_int32(env, value, &result);
        return result;
    }
    static bool Validate(napi_env env, napi_value value) {
        napi_valuetype type;
        napi_typeof(env, value, &type);
        return type == napi_number;
    }
};

template <> struct NapiValueConverter<uint32_t> {
    static napi_value From(napi_env env, const uint32_t &value) {
        napi_value result;
        napi_create_uint32(env, value, &result);
        return result;
    }
    static uint32_t As(napi_env env, napi_value value) {
        uint32_t result;
        napi_get_value_uint32(env, value, &result);
        return result;
    }
    static bool Validate(napi_env env, napi_value value) {
        napi_valuetype type;
        napi_typeof(env, value, &type);
        return type == napi_number;
    }
};

template <> struct NapiValueConverter<bool> {
    static napi_value From(napi_env env, const bool &value) {
        napi_value result;
        napi_get_boolean(env, value, &result);
        return result;
    }
    static uint32_t As(napi_env env, napi_value value) {
        bool result;
        napi_get_value_bool(env, value, &result);
        return result;
    }
    static bool Validate(napi_env env, napi_value value) {
        napi_valuetype type;
        napi_typeof(env, value, &type);
        return type == napi_boolean;
    }
};

template <> struct NapiValueConverter<long> {
    static napi_value From(napi_env env, const long &value) {
        napi_value result;
        napi_create_int64(env, value, &result);
        return result;
    }
    static long As(napi_env env, napi_value value) {
        long result;
        napi_get_value_int64(env, value, &result);
        return result;
    }
    static bool Validate(napi_env env, napi_value value) {
        napi_valuetype type;
        napi_typeof(env, value, &type);
        return type == napi_number;
    }
};

template <> struct NapiValueConverter<size_t> {
    static napi_value From(napi_env env, const size_t &value) {
        napi_value result;
        napi_create_int64(env, static_cast<int64_t>(value), &result);
        return result;
    }
    static size_t As(napi_env env, napi_value value) {
        uint32_t result;
        napi_get_value_uint32(env, value, &result);
        return static_cast<size_t>(result);
    }
    static bool Validate(napi_env env, napi_value value) {
        napi_valuetype type;
        napi_typeof(env, value, &type);
        return type == napi_number;
    }
};

template <typename T> static T As(napi_env env, napi_value value) { return NapiValueConverter<T>::As(env, value); }
template <typename T> static T As(napi_env env, napi_value value, T default_value) {
    if (NapiValueConverter<T>::Validate(env, value)) {
        return NapiValueConverter<T>::As(env, value);
    }
    return default_value;
}


template <typename T> static napi_value From(napi_env env, const T &value) {
    return NapiValueConverter<T>::From(env, value);
}

#endif // STREAMCORE_CONVERTER_H
